/**
 *
 */
package com.angel.annotation.finders;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;

import com.angel.annotation.exceptions.AnnotationManagerException;
import com.angel.annotation.interfaces.AnnotationObjectFinder;
import com.angel.common.helpers.ReflectionHelper;

/**
 *
 * @author William
 *
 */
public class AnnotationFieldFinder implements AnnotationObjectFinder{

	private static AnnotationObjectFinder instance;

	private AnnotationFieldFinder(){
		super();
	}

	public static synchronized AnnotationObjectFinder getInstance(){
		if(instance == null){
			instance = new AnnotationFieldFinder();
		}
		return instance;
	}

	public <T extends Annotation> Annotation findAnnotationAt(Object object, Class<T> annotationClass){
		Annotation annotation = null;
		int quantity = 0;
		Field[] fields = ReflectionHelper.getFieldsDeclaredFor(object.getClass());
		if(fields != null && fields.length > 0){
			for(Field field: fields){
				annotation = field.getAnnotation(annotationClass);
				if( annotation != null){
					quantity++;
				}
			}
		}
		if(quantity > 1){
			throw new AnnotationManagerException("Object has more than one annotation implementation for [" + annotationClass.getCanonicalName() + "].");
		}
		return annotation;
	}

	public <T extends Annotation> Object findTargetObjectFor(Object object, Class<T> annotationClass) {
		Annotation annotation = this.findAnnotationAt(object, annotationClass);
		Field[] fields = ReflectionHelper.getFieldsDeclaredFor(object.getClass());
		if(fields != null && fields.length > 0){
			for(Field field: fields){
				annotation = field.getAnnotation(annotationClass);
				if( annotation != null){
					return field;
				}
			}
		}
		return null;
	}

}
